<template>
  <div class="app-container">
    <div class="custom-tree-container">
      <div class="block">
        <el-button
          icon="el-icon-check"
          style="color:#67c23a"
          type="text"
          size="mini"
          @click="() => append({id: 0,title: '无'})"
        >
          添加顶级菜单
        </el-button>
        <el-tree
          v-loading="listLoading"
          :data="menu"
          node-key="id"
          :highlight-current="true"
          default-expand-all
          :props="{children:'child'}"
          :expand-on-click-node="false"
        >
          <span slot-scope="{ node, data }" class="custom-tree-node">
            <span>{{ data.id }}-{{ data.title }}[{{ data.name }}]</span>
            <span>
              <el-button
                icon="el-icon-check"
                style="color:#67c23a"
                type="text"
                size="mini"
                @click="() => append(data)"
              >
                添加
              </el-button>
              <el-button
                style="color:#f56c6c"
                icon="el-icon-delete"
                type="text"
                size="mini"
                @click="() => remove(node, data)"
              >
                删除
              </el-button>
              <el-button
                icon="el-icon-edit"
                style="color:#e6a23c"
                type="text"
                size="mini"
                @click="() => modify(node, data)"
              >
                修改
              </el-button>
            </span>
          </span>
        </el-tree>
      </div>

      <el-dialog :title="textMap[dialogStatus]" :visible.sync="dialogFormVisible">
        <el-form
          ref="dataForm"
          :rules="rules"
          :model="temp"
          label-position="left"
          label-width="70px"
          style="width: 400px; margin-left:50px;"
        >
          <el-form-item v-if="['create'].includes(dialogStatus)" label="父级菜单" prop="pTitle">
            <el-input v-model="temp.pTitle" placeholder="" :readonly="['create','update'].includes(dialogStatus)" />
          </el-form-item>
          <el-form-item v-if="['update','create'].includes(dialogStatus)" label="菜单名" prop="title">
            <el-input v-model="temp.title" placeholder="请输入菜单名称" />
          </el-form-item>
          <el-form-item v-if="['update','create'].includes(dialogStatus)" label="英文名" prop="name">
            <el-input v-model="temp.name" placeholder="请输入英文名称" />
          </el-form-item>
        </el-form>
        <div slot="footer" class="dialog-footer">
          <el-button @click="dialogFormVisible = false">
            取消
          </el-button>
          <el-button type="primary" @click="dialogStatus==='create'?createData():updateData()">
            确认
          </el-button>
        </div>
      </el-dialog>

      <el-dialog :visible.sync="dialogPvVisible" title="Reading statistics">
        <el-table :data="pvData" border fit highlight-current-row style="width: 100%">
          <el-table-column prop="key" label="Channel" />
          <el-table-column prop="pv" label="Pv" />
        </el-table>
        <span slot="footer" class="dialog-footer">
          <el-button type="primary" @click="dialogPvVisible = false">Confirm</el-button>
        </span>
      </el-dialog>
    </div>
  </div>
</template>

<script>
import { addMenu, modifyMenu, removeMenu, treeMenu } from '@/api/user/menu-manager'
import waves from '@/directive/waves' // waves directive
import { parseTime } from '@/utils'
import { validAlphabets } from '@/utils/validate'

const calendarTypeOptions = [
  { key: 'CN', display_name: 'China' },
  { key: 'US', display_name: 'USA' },
  { key: 'JP', display_name: 'Japan' },
  { key: 'EU', display_name: 'Eurozone' }
]

// arr to obj, such as { CN : "China", US : "USA" }
const calendarTypeKeyValue = calendarTypeOptions.reduce((acc, cur) => {
  acc[cur.key] = cur.display_name
  return acc
}, {})
export default {
  name: 'MenuManager',
  directives: { waves },
  filters: {
    statusFilter(status) {
      const statusMap = {
        1: 'success',
        0: 'danger'
      }
      return statusMap[status]
    },
    typeFilter(type) {
      return calendarTypeKeyValue[type]
    }
  },
  data() {
    return {
      curData: {},
      menu: [],
      tableKey: 0,
      list: null,
      total: 0,
      listLoading: true,
      listQuery: {
        pageNum: 1,
        pageSize: 10,
        nickName: ''
      },
      importanceOptions: [1, 2, 3],
      calendarTypeOptions,
      sortOptions: [{ label: 'ID Ascending', key: '+id' }, { label: 'ID Descending', key: '-id' }],
      statusOptions: [{ key: '1', text: '启用' }, { key: '0', text: '禁用' }],
      showReviewer: false,
      temp: {
        id: '',
        pTitle: '',
        title: '',
        parentId: '',
        name: '',
        icon: 'icon',
        child: []
      },
      dialogFormVisible: false,
      dialogStatus: '',
      textMap: {
        update: '修改',
        create: '添加'
      },
      dialogPvVisible: false,
      pvData: [],
      rules: {},
      downloadLoading: false
    }
  },
  created() {
    this.getList()
  },
  methods: {
    open() {
      this.$message({
        showClose: true,
        message: '请先删除子菜单',
        type: 'warning'
      })
    },
    getList() {
      this.listLoading = true
      treeMenu({}).then(response => {
        const { data } = response
        this.menu = JSON.parse(JSON.stringify(data))
        this.listLoading = false
      })
    },
    // 添加菜单
    append(data) {
      this.rules = {
        title: [{ required: true, trigger: ['blur', 'change'], message: '菜单名称不能为空' }],
        name: [{ required: true, trigger: ['blur', 'change'], validator: validAlphabets }]
      }
      this.resetTemp()
      this.temp.pTitle = data.title
      this.temp.parentId = data.id
      this.dialogStatus = 'create'
      this.dialogFormVisible = true
      this.curData = data
      data = this.curData
      this.$nextTick(() => {
        this.$refs['dataForm'].clearValidate()
      })
    },
    // 添加菜单
    modify(node, data) {
      this.rules = {
        title: [{ required: true, trigger: ['blur', 'change'], message: '菜单名称不能为空' }],
        name: [{ required: true, trigger: ['blur', 'change'], validator: validAlphabets }]
      }
      this.resetTemp()
      this.temp.id = data.id
      this.temp.title = data.title
      this.temp.name = data.name
      this.temp.parentId = data.parentId
      this.dialogStatus = 'update'
      this.dialogFormVisible = true
      this.curData = data
      data = this.curData
      this.$nextTick(() => {
        this.$refs['dataForm'].clearValidate()
      })
    },
    remove(node, data) {
      this.listLoading = true
      if (data.child && data.child.length > 0) {
        this.listLoading = false
        return this.open()
      }
      // 删除菜单
      removeMenu({ id: data.id }).then(() => {
        this.listLoading = false
        this.$notify({
          title: '成功',
          message: '删除成功',
          type: 'success',
          duration: 2000
        })
        const parent = node.parent
        const child = parent.data.child || parent.data
        const index = child.findIndex(d => d.id === data.id)
        child.splice(index, 1)
      })
    },
    handleFilter() {
      this.listQuery.pageNum = 1
      this.getList()
    },
    handleModifyStatus(row, status) {
      this.$message({
        message: '操作Success',
        type: 'success'
      })
      row.status = status
    },
    sortChange(data) {
      const { prop, order } = data
      if (prop === 'id') {
        this.sortByID(order)
      }
    },
    sortByID(order) {
      if (order === 'ascending') {
        this.listQuery.sort = '+id'
      } else {
        this.listQuery.sort = '-id'
      }
      this.handleFilter()
    },
    resetTemp() {
      this.temp = {
        id: '',
        pTitle: '',
        title: '',
        parentId: '',
        name: '',
        icon: 'icon',
        child: []
      }
    },
    createData() {
      this.$refs['dataForm'].validate((valid) => {
        if (valid) {
          addMenu(this.temp).then(response => {
            const { data } = response
            const newChild = { id: data, title: this.temp.title, name: this.temp.name, child: [] }
            if (this.temp.parentId === 0) {
              this.menu.push(newChild)
            } else {
              this.curData.child.push(newChild)
            }
            this.dialogFormVisible = false
            this.$notify({
              title: '成功',
              message: '添加成功',
              type: 'success',
              duration: 3000
            })
          })
        }
      })
    },
    updateData() {
      this.$refs['dataForm'].validate((valid) => {
        if (valid) {
          modifyMenu(this.temp).then(() => {
            this.curData.title = this.temp.title
            this.curData.name = this.temp.name
            this.dialogFormVisible = false
            this.$notify({
              title: '成功',
              message: '修改成功',
              type: 'success',
              duration: 2000
            })
          })
        }
      })
    },
    formatJson(filterVal) {
      return this.list.map(v => filterVal.map(j => {
        if (j === 'timestamp') {
          return parseTime(v[j])
        } else {
          return v[j]
        }
      }))
    },
    getSortClass: function(key) {
      const sort = this.listQuery.sort
      return sort === `+${key}` ? 'ascending' : 'descending'
    }
  }
}
</script>
<style>
  .custom-tree-node {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: space-between;
    font-size: 14px;
    padding-right: 8px;
  }
</style>

